
import re
import time
import traceback

import requests
import win32con
import win32gui
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import ActionChains
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from Basic.img_code import ImgHandle
from Basic.read_ini import ReadIni
from Basic.base_log import log
from Basic.read_re import re_get,re_sub
from Basic.PATH import *
class OperateElement(object):
    def __init__(self, driver, add_img ):
        self.driver = driver
        self.add_img = add_img
        # self.get_assert = get_assert
        # self.var_dict = var_dict

        self.readini = ReadIni()
        self.code_path = self.readini.get_value('path', 'code_path')
        # self.code_path ='%s\\Logs\\getCode.jpg'% os.getcwd()

    def opera_element(self, ele, dict):
        # case_module =     dict['用例模块']
        # case_id =         dict['编号']
        # precondition = dict['前提条件']
        operate_step =    dict['操作步骤']
        element_operate = dict['操作元素']
        element_method =    dict['元素定位方式']
        elemernt_action =    dict['元素动作']
        element_sendkey =         dict['输入数据']
        # time_sleep =      dict['延时']
        # bool_execute =    dict['是否执行']
        # expect_results =  dict['预期结果']
        # test_results =    dict['实测结果']
        # test_report =     dict['测试报告']

        # 断言如何一对多
        assert_ele = dict['断言元素']
        assert_ele_method = dict['断言元素方法']
        assert_ele_action = dict['断言元素动作']
        assert_method = dict['断言方法']
        expect_result = dict['预期结果']
        assert_result = dict['断言结果']

        try:
            if elemernt_action == 'click':
                ele.click()
            elif elemernt_action == 'sendkey':
                ele.clear()
                ele.send_keys(str(element_sendkey))
            elif elemernt_action == 'text':
                if element_sendkey is None and element_sendkey == '':
                    ele = ele.text
                    log.info('--   --> %s:%s ' % (operate_step, ele))
                    return ele
                relist = element_sendkey.split(':')
                #元素文本中有冒号处理
                stre = ''
                if len(relist)>2:
                    for r in relist:
                        if r != relist[-1]:
                            stre = stre + r
                ele = re_get(ele.text, relist[-1]) #取出符合正则的内容
                log.info('--   --> %s:%s ' % (operate_step, ele))
                return ele
            elif elemernt_action == 'waitele':
                return ele
            elif elemernt_action == 'upload':
                #先获取元素位置并坐标点击，通过win窗口上传文件，
                self.upload_ele(self.driver, ele,element_sendkey)
                # ele.send_keys(element_sendkey) #原始上传方式
                # print(ele.get_attribute('value'))
                return ele
            elif elemernt_action == 'hover':
                ActionChains(self.driver).move_to_element(ele).perform()
                ele = 1
            elif elemernt_action == 'clickxy_ele':
                if element_sendkey is not None and element_sendkey != '':
                    x = element_sendkey.split(',')[0]
                    y = element_sendkey.split(',')[1]
                else:
                    x = y = None
                if ele == 1:
                    self.clickxy_ele(self.driver, None, x, y)
                else:
                    self.clickxy_ele(self.driver, ele, x, y)
            elif elemernt_action == 'checkbox0':  # 未勾选勾选
                if ele.is_selected() == False:
                    log.info('--   --> %s: ' % (operate_step))
                    ele.click()
            elif elemernt_action == 'checkbox1':  # 已勾选取消勾选
                if ele.is_selected() == True:
                    log.info('--   --> %s: ' % (operate_step))
                    ele.click()
            elif elemernt_action == 'scroll':  # 滚动屏幕至某个可见元素位置
                self.driver.execute_script("arguments[0].scrollIntoView();", ele)
            elif elemernt_action == 'handle':  # 切换标签页
               self.switch_handle(dict)
            elif elemernt_action == 'iframe':
                self.driver.switch_to.frame(ele)
            elif elemernt_action == 'url':
                self.driver.get(element_operate)
            elif elemernt_action == 'ifele':
                if ele != 'ERROR':
                    log.info('-- TRUE --> 元素存在 ')
                else:
                    log.info('-- False --> 元素不存在 ')
                return True
            elif elemernt_action == 'ifclick':
                if ele != 'ERROR':
                    log.info('--   -->  该元素存在，点击删除')
                    ele.click()
                else:
                    log.info('--   --> 该元素不存在 ')
                return True
            elif elemernt_action == 'screenshot':
                self.add_img()  # 截图
            elif elemernt_action == 'getcode':
                log.info('--   -->  %s'% self.code_path)
                ele = ImgHandle().get_ele_code(self.driver, ele, self.code_path)
                var_dict['getcode'] = ele
                return ele #返回验证码
            elif elemernt_action == 'get_var':
                # 把操作元素中的文本，根据输入数据中的正则表达式，提取出变量名和变量值。输入数据中格式为var:正则表达式。提取多个变量用英文逗号隔开
                # 提取输入数据中的正则表达式和变量名
                relist = element_sendkey.split(',')
                for q in relist:
                    qlist = q.split(':')  # 变量名qlist[0]，变量正则表达式qlist[-1]，原数据：element_operate
                    getlist = re_get(element_operate, qlist[-1])
                    # log.info('根据正则表达式提取的值: %s' % getlist[0])
                    self.readini.set_value('var_dict', qlist[0], getlist[0])
                    var_dict[qlist[0]] = getlist[0]
                    log.info('--   --> 设置变量 %s = %s' % (qlist[0], var_dict[qlist[0]]))
                    #全局解析变量
                return True
            elif elemernt_action == 'sup_var':
                #将文本中的变量名替换为值
                return True
            elif elemernt_action == 'set_var':
                #设置全局变量，如果操作元素中有填写元素地址，则可获取文本内容
                relist = element_sendkey.split(',')
                if ele == 1:
                    for q in relist:
                        qlist = q.split(':')  # 变量名qlist[0]，变量值qlist[-1]
                        var_dict[qlist[0]] = qlist[-1]
                        log.info('--   --> 设置变量 %s = %s' % (qlist[0], var_dict[qlist[0]]))
                else:
                    for q in relist:
                        qlist = q.split(':')  # 变量名qlist[0]，变量正则表达式qlist[-1]，原数据：element_operate
                        getlist = re_get(ele.text, qlist[-1])
                        # log.info('根据正则表达式提取的值: %s' % getlist[0])
                        # self.readini.set_value('var_dict', qlist[0], getlist[0])
                        var_dict[qlist[0]] = getlist[0]
                        log.info('--   --> 设置变量 %s = %s' % (qlist[0], var_dict[qlist[0]]))
                return var_dict
            elif elemernt_action == 'requests':
                headers=element_sendkey
                return requests.get(operate_step,headers=headers).text
            elif elemernt_action == 'get_sql':
                relist = element_sendkey.split(':')
                var_dict[relist[0]] = relist[-1]
            elif elemernt_action == 'get_table':
                tblist = ele
                if element_sendkey is None and element_sendkey == '':
                    var_dict['tb_'] = tblist
                    return True
                #通过输入数据中的规则提取对应的值,格式为 col:标题名,row:10,var:自定义变量名。data为非必填
                ilist = element_sendkey.split(',')
                var =var1=var2=None
                for i in ilist:
                    if 'col' == i.split(':')[0]:
                        col = i.split(':')[-1]
                    if 'row' == i.split(':')[0]:
                        row =i.split(':')[-1]
                    if 'var1' == i.split(':')[0]:
                        var1 =i.split(':')[-1]
                    if 'var2' == i.split(':')[0]:
                        var2 =i.split(':')[-1]
                    if 'var' == i.split(':')[0]:
                        var = i.split(':')[-1]
                # print(type(var))
                if var:
                    var_dict[var] = tblist   #保存整个表格数据到全局变量
                if var1 is not None:
                    var_dict[var1] = tblist[int(row) - 1] #保存整行表格数据到全局变量
                if var2 is not None:
                    var_dict[var2] = tblist[int(row) - 1][col] #保存单元格数据到全局变量
                log.info('--   --> 保存到全局变量var_dict:%s' % var_dict)
                return True
            elif elemernt_action == 'assert':
                try:
                    self.add_img()
                    # self.get_assert(element_method, expect_results, test_results)
                    ele = 'PASS'
                except :
                    ele =  'FAIL %s'% traceback.format_exc()
                    error_log = traceback.format_exc()  # 打印异常信息
                    log.info("××××××××××××××××××element_operate 出错××××××××××××××××××\n %s" % error_log)
            return ele  # ele返回元素
        except :
            error_log = "*××××××××××××××××××element_operate 出错××××××××××××××××××\n %s" % traceback.format_exc()  # 打印异常信息
            # self.readini.set_value('error', 'error_log', error_log)
            log.info(error_log)
            return False

    def upload_ele(self, driver, ele, upload_file):
        self.clickxy_ele(driver, ele)
        time.sleep(2)
        # win32gui
        dialog = win32gui.FindWindow('#32770', u'打开')  # 查找对话框
        ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None)  #
        ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
        Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None)  # 上面三句依次寻找对象，直到找到输入框Edit对象的句柄
        button = win32gui.FindWindowEx(dialog, 0, 'Button', None)  # 确定按钮Button
        win32gui.SendMessage(Edit, win32con.WM_SETTEXT, None, upload_file)  # 往输入框输入绝对地址
        win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button)  # 按button
        time.sleep(1)

    def clickxy_ele(self, driver, ele=None, x=5, y=5):
        if ele:
            x = ele.location.get('x')  # 获取元素的x坐标
            y = ele.location.get('y')  # 获取元素的y坐标

        else:
            time.sleep(1)
        # log.info(f'x={x},y={y}')
        ActionChains(driver).move_by_offset(x + 5, y + 5).click().perform() #通过元素坐标偏移点击该元素

    # 切换标签页：
    def switch_handle(self, dict):
        all_handles = self.driver.window_handles  # 获取全部页面句柄
        # log.info('--   --> 获取全部标签页：%s' % all_handles)
        if '关闭标签页' in dict['操作元素']:
            self.driver.close()
        if '切换标签页' in dict['操作元素']:
            num = int(re.findall(r"\d", dict['操作元素'])[0])  # 正则表达式，获取字符串中的数字
            self.driver.switch_to.window(all_handles[num])  # 切换到新页面
            log.info('--   --> 已切换到标签页：%s' % self.driver.title)
        return self.driver.title

    def ismaohao(self, relist):
        # 元素文本中有冒号处理
        stre = ''
        if len(relist) > 2:
            for r in relist:
                if r != relist[-1]:
                    stre = stre + r
        return stre

if __name__ == "__main__":
    # filname = 'E://PythonWorkspace//RunTest//LZ_Element.xlsx'
    # datatime = time.strftime('%Y-%m-%d %H.%M.%S', time.localtime(time.time()))  # 创建时间
    # sheetname = '6101'
    # # 初始化 seleium
    # driver = webdriver.Chrome()
    # driver.maximize_window()
    #
    # excel = base_03_openpyxlExcel.GetExcel(filename=filname, sheetname=sheetname)
    # list = excel.get_excel_h(case='LOGIN')  # 获取用例模块所在行数区间
    # # log.info(list)
    #
    # fm = FindElement(driver, datatime)
    #
    # for i in range(len(list)):
    #     dict = excel.get_excel_v(list[i])
    #     # log.info('获取指定行数内容dict : %s' % dict)
    #     # log.info('%s:%s' % (dict['操作步骤'], dict['输入数据']))
    #     fm.opera_element(dict)
    pass
